package cn.dglydrpy.study.smartmvc.base.common;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import cn.dglydrpy.study.smartmvc.base.annotation.RequestMapping;

/*
 * 映射处理器 负责提供请求路径与处理器之间的关系
 */
public class HandlerMapping {
	
	/**
	 * handlerMap 用于映射 请求 path 到对应的请求处理器
	 * 如：将 /emp/list.do 映射到 bizColtroller.list()方法
	 */
	private Map<String, RequestHandler> handlerMap = new HashMap<>();
	
	public RequestHandler getHandler(String path){//通过请求路径得到相应的处理器实例
		return handlerMap.get(path);
	}
	
	/*
	 * 遍历集合通过反射读取@RequestMapping注解中的路径信息
	 */
//	public void execute(List beans) {
//		for (Object bean : beans) {
//			//通过实例找到Class对象
//			Class cls = bean.getClass();
//			Method[] methods = cls.getDeclaredMethods();
//			for (Method method : methods) {
//				//找到方法前的注解
//				RequestMapping rm = method.getDeclaredAnnotation(RequestMapping.class);
//				String path = rm.value();
//				System.out.println("path:"+path);
//				//建立请求路径和处理器的关系
//				handlerMap.put(path, new RequestHandler(method,bean));
//			}
//		}
//		System.out.println("map:"+handlerMap);
//	}
	
	/**
	 * 用于根据 path 执行对应控制器方法
	 * @param path 请求路径
	 * @param request 执行控制器时候的参数
	 * @return 控制器执行以后的返回值
	 */
	public String execute(String path, HttpServletRequest request) throws Exception {
		RequestHandler handler = getHandler(path);
		Method method = handler.getMethod();
		Object controller = handler.getController();
		Object val = method.invoke(controller, request);
		String value = (String)val;
		return value;
	}
	
	/**
	 * 初始化方法：解析控制器中的注解，将注解和注解标注的方法添加到 map中
	 * @param className 控制器类名
	 */
	public void init(String className) throws Exception{
		Class cls = Class.forName(className);
		Method[] methods = cls.getDeclaredMethods();
		Object controller = cls.newInstance();
		for(Method method:methods) {
			RequestMapping ann = method.getAnnotation(RequestMapping.class);
			if(ann!=null) {
				//找到注解上标注的路径
				String path=ann.value();
				//创建请求处理器对象，封装控制器对象和方法
				RequestHandler handler=new RequestHandler(method,controller);
				//请求路径和对应的“请求处理器”添加到map
				handlerMap.put(path, handler);
			}
		}
	}
}
